/***************************************************************************
 *   Copyright (C) 2011 by The rPem3d developers                           *
 *   elseifkk@users.sf.net                                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef CLRUNCLS_H
#define CLRUNCLS_H

#include <sys/time.h>

#include "clrunDlg.h"
#include "cvcls.h"

#define CONFIG  ".clrunrc"
#define SHM2FILE "/usr/local/pem/bin/shm2file"

#include <qdatetime.h>
#include <qprocess.h>
#include <qmutex.h>

int const locpos=8+8+16+16; /* offset to the LMD pointer */

int const CHART_ADJ_CYCLE=20;
int const MAX_READ_COUNT=4;
int const DF_COIN=0;
int const DF_SLUT=1;
int const DF_SRAW=2;
int const MASK30=0x40000000;
int const MASK31=0x80000000;
int const MASK28=0x10000000;
int const numcbuf=11;
int const numpbuf=10;
int const numdet=8;
float const bar_chart_max_def=100.;
int const CID_TOTAL=8;
int const CID_ACCEPT=9;
int const CID_DELAYED=10;
int const clock_interval=120; //<<<<<<<<<<<<<<<<<<<<<<<<<<<
int const lmd_file_size = 5898240;

QColor const bcol_ready=qRgb(231, 233, 238);
QColor const bcol_off=qRgb(163, 164, 168);
QColor const btcol_off="black";
QColor const bcol_on="greenyellow";
QColor const btcol_on=qRgb(219,94,94);
QColor const btcol_ready="royalblue";

int const namax=512;
int const ntmax=512;
int const na=20;
int const nt=64;
int const ndh=4;
int const nd=ndh*2;

int const chist_size = na*nt*ndh*na*nt*ndh*2*sizeof(int);
int const shist_size = na*nt*nd*sizeof(int);
int const rhist_size = namax*ntmax*nd*sizeof(int);
int const chist_off = 0;
int const shist_off = chist_size;
int const rhist_off=shist_off+shist_size;

class clRunCls: public clRunDlg {
    Q_OBJECT

public:
    clRunCls(QWidget *parent = 0, const char *name = 0);
    ~clRunCls();

private:
    void procLEDs();
    void resetLEDs(bool);
    void anaProc(int);
    void resetCounts();
    bool isValidId();
    void showError(QString);
    void readLMD(int *start, size_t len);
    void decCoin(int *start, size_t len);
    void decSLUT(int *start, size_t len);
    void decRAW(int *start, size_t len);
    void displayCps(QLCDNumber *d, float x);
    void setButOn(QPushButton *b, bool on, bool ready=false);
    void displayCount(QLCDNumber *d, int x);
    size_t updateLoc();
    double count2cps(double,double);
    void getLoc();
    double dT();
    void saveConfig(QString);
    void loadConfig(QString);
    void updateBarCharts();
    void initHists();
    void resetHists();
    void initButStats();
    void setButReady(QPushButton*,bool);
    void initDisplay();
    void setDAQDateTime();
    void printShmLabel();
    QString foutSuffix();
    void switchLed(KLed *, bool);
    double atimeDiffs[numcbuf];
    double lastCpss[numcbuf];

 private:
    void *oshm;
    int oshmid;
    int currentFormat;
    int shmid;
    size_t shmsz;
    int uid;
    int ledCount;
    double timeDiff;
    int *listData;
    int *endListData;
    int *firstListData;
    QMutex readMT;
    int timerid;
    QTimer *readt;
    QTimer *readallt;
    size_t cls[3];
    bool startRead;
    size_t theFirstLoc;
    size_t currentLoc;
    size_t lastLoc;
    struct timezone tz;
    struct timeval currentTime, lastTime;
    struct timeval daqStartTime, startTime; // for stop watch
    time_t theOldDt, theOldmDt;
    bool timerOn;
    QString HOME;
    int readCount;
    int adjCount;
    double meanTotalCps;
    double maxTotalCps;
    double chartMax;

    size_t recvd;
    int counts[numcbuf];
    int acounts[numcbuf];
    int totalcounts[numcbuf];
    QLCDNumber *lcds[numpbuf];
    QLCDNumber *lcdas[numpbuf];
    AnalogMeter *amts[numpbuf];
    KLed *leds[numpbuf];
    BarChart *bcs[numpbuf];
    float chartBuf[256];
    int *totalCount;
    int *acceptCount;
    int *delayedCount;
    int *totalCountA;
    int *acceptCountA;
    int *delayedCountA;
    double *atimeDiffTotal;
    double *atimeDiffAccept;
    double *atimeDiffDelayed;
    double *lastCpsTotal;
    double *lastCpsAccept;
    double *lastCpsDelayed;
    double theDenom;

    int totalEvent;
    int acceptEvent;
    int delayedEvent;

    bool setKeyOn;
    bool attachOn;
    bool attachReady;
    bool coinOn;
    bool rawOn;
    bool singleOn;
    bool acceptOn;
    bool cpsOn;
    bool saveHistOn;
    bool saveLMDOn;
    bool outDirReady;

    size_t lmdsz,lmdstart;

    int *chist;
    int *shist;
    int *rhist;

    CrystalViewer *cvs[numdet];
    bool anaOn[numdet];
    QPushButton *anbs[numdet];

    QDateTime DAQStartDateTime;
    QDateTime DAQEndDateTime;
    QString DAQDateTimeStr;
    bool receiving;
    bool allread;
    QProcess *shproc;
    QProcess *slproc;

    bool elapsedOn;
    bool truncated;

private slots:
    void dataFormatSlotC();
    void dataFormatSlotR();
    void timerClearSlot();
    void timerStopSlot();
    void timerStartSlot();
    void dataFormatSlotS();
    void openPathSlot();
    void detachSlot();
    void resetSlot();
    void ana7Slot();
    void ana6Slot();
    void ana5Slot();
    void ana4Slot();
    void ana3Slot();
    void ana2Slot();
    void ana1Slot();
    void ana0Slot();
    void attachSlot();
    void shmidSlot();
    void readSlot();
    void setKeySlot();
    void setIdSlot();
    void cpsSlot();
    void ratioSlot();
    void delSlot();
    void outputDirSlot();
    void acceptSlot();
    void saveListSlot();
    void saveHistSlot();
    void openOutputDirSlot();
    void anaDone(int);
    void elapsedSlot();
    void shDone();
    void slDone();
    void loadAllSlot();
    void readAllSlot();

protected:
    void closeEvent(QCloseEvent*e);
};
#endif
